/***************************************************************
 * Name:      LuaInterface.h
 * Purpose:   Defines the Lua Interface functions and classes
 * Author:    Milind Gupta (milind.gupta@gmail.com)
 * Website:   https://code.google.com/p/ganitsheets/
 * Created:   2011-03-02
 * Copyright: Milind Gupta ()
 * License:   Apache License 2.0
 **************************************************************/

#ifndef __GANITS_LUAINTERFACE_H
#define __GANITS_LUAINTERFACE_H

#include "Globals.h"
#include "CoreStructs.h"
#include <string>

int LuaFunctionCall(lua_State *L);                  // Function to dispatch the Lua call to the appropriate object
struct retPacket runLuaFile(std::string LuaFile);   // Function to run the indicated Lua File

// Class from which every object that needs accessibility from the Lua script must inherit from
class luaObj
{
    public:
        virtual int LuaScriptCall(int funcIndex)=0;

    protected:
        struct luaAPIStruct
        {
            int funcIndex;
            std::string funcName;   // Name of the function as known to Lua
            std::string tableHier;  // Table hierarchy where the function has to be placed"
                                    // A.B means to place this in table B which is inside table A
            bool overWrite;         // If true then if a function with the same name exists then it is overwritten with this
            bool overRidePrefix;    // If true then even if prefixing requested to the registering function will not be prefixed for this function
            void *data;             // Pointer to the data if any to be stored
        };
        static luaAPIStruct emptyLuaAPI[];
        explicit luaObj(luaAPIStruct luaObjAPIpassed[], \
            luaAPIStruct luaStaticAPIpassed[]) : \
            luaObjAPI(luaObjAPIpassed), luaStaticAPI(luaStaticAPIpassed) {}
        explicit luaObj(luaAPIStruct luaObjAPIpassed[]) : luaObjAPI(luaObjAPIpassed) \
        {luaStaticAPI = emptyLuaAPI;}
        luaAPIStruct *luaObjAPI, *luaStaticAPI;

        // API Registering functions

        // Registers the static API of the object on to the Global table as a reference
        void registerLuaStaticAPI(std::string hierPrefix="");
        // Creates a Lua Table and returns it on top of the stack with the luaObjAPI
        // defined relative to it
        void returnAPITable(std::string hierPrefix="");
        // Creates a new Lua table with the luaObjAPI and then places the table in the
        // GLobal table with the passed table name
        void registerAPITableonGlobal(std::string tableName, std::string hierPrefix="");
        // Creates a light user data with the reference table in the registry.
        // The reference table containing the luaObjAPI
        void returnAPILud(std::string hierPrefix="");
        // Creates the light user data with luaObjAPI and then places that light user data
        // on the global table with the passed name
        void registerAPILudonGlobal(std::string ludName, std::string hierPrefix="");
    private:
        // API registering core function. All above functions call this one
        void registerLuaAPITable(const luaAPIStruct *luaAPI, int tableIndex, \
                                 std::string hierPrefix);
};

#endif
